﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using Meraz.Web.Models;
using Meraz.Core.Managers;
using Ninject;
using Meraz.Core.Model;
using Meraz.Web.Filters;
using Spark.Web.Mvc;
using Spark;
using Spark.FileSystem;
using Meraz.Web.Views.Helpers;

namespace Meraz.Web.Controllers
{
    [RolesAuthorize(Roles = UserRoles.KeyMaster)]
    public class BlogController : Controller
    {
        [Inject]
        public PostManager PostManager { get; set; }

        [Inject]
        public BlogManager BlogManager { get; set; }
        //
        // GET: /BlogStudy/
        /// <summary>
        /// Presents a description for each discreet function in the BlogStudy
        /// </summary>
        /// <returns></returns>
        public ActionResult Index(string id)
        {
            ViewData["Menu"] = Menu.Blog;
            if (string.IsNullOrWhiteSpace(id))
            {
                //no specific study was selected
            }
            

            //BlogStudyModel model = new BlogStudyModel();
            //model.Study = StudyManager.Get(id);
            //model.Blogs = BlogManager.GetBlogsInStudy(id).ToList();
            //return View(model);
            return View(new PostModel());
        }


        [HttpPost]
        public ActionResult Load(PostModel postModel)
        {
            ViewData["Menu"] = Menu.Blog;
            PostModel model = new PostModel();
            if (postModel != null && postModel.Post != null && !string.IsNullOrWhiteSpace(postModel.Post.Permalink))
            {
                model.Post = PostManager.GetFromUrl(postModel.Post.Permalink);
                return View("EditPost", model);
            }
            return View("LoadPost", model);
        }
        public ActionResult Studies()
        {
            ViewData["Menu"] = Menu.Blog;
            StudyListModel<BlogStudy> model = new StudyListModel<BlogStudy>();
            model.Studies = BlogManager.GetStudies();
            return View(model);
        }

        public ActionResult ViewBlogs(string StudyID)
        {
            ViewData["Menu"] = Menu.Blog;
            BlogStudyModel model = new BlogStudyModel();
            model.Study = BlogManager.GetStudy(int.Parse(StudyID));
            model.Blogs = model.Study.Blogs;
            return View(model);
        }

        public ActionResult ViewPeople(int StudyID)
        {
            ViewData["Menu"] = Menu.Blog;
            BlogStudyModel model = new BlogStudyModel();

            return View(model);
        }

        public ActionResult ViewTopics(int StudyID)
        {
            ViewData["Menu"] = Menu.Blog;
            BlogStudyModel model = new BlogStudyModel();

            return View(model);
        }

        [ObjectFilter(Param = "model", RootType = typeof(PosterModel))]
        [HttpPost]
        public ActionResult AddPoster(PosterModel model)
        {
            int postID = model.PostID;
            string aliasName = model.AliasName;
            Poster poster = PostManager.AddPoster(postID, aliasName);
            HtmlModel result = new HtmlModel();
            if (poster == null)
            {
                result.Message = "Invalid";
            }
            else
            {
                result.Message = "Added Alias!";
                result.Html = BlogStudyHelper.CreatePosterOption(poster);
            }
            return Json(result);
        }

        [ObjectFilter(Param = "model", RootType = typeof(LinkModel))]
        [HttpPost]
        public ActionResult AddLink(LinkModel model)
        {
            int postID = model.PostID;
            string href = model.Href;
            Link link = PostManager.AddLink(postID, href);
            HtmlModel result = new HtmlModel();
            if (link == null)
            {
                result.Message = "Invalid";
            }
            else
            {
                result.Message = "Added Link!";
                result.Html = BlogStudyHelper.CreateLinkOption(link);
            }
            return Json(result);
        }

        [ObjectFilter(Param = "model", RootType = typeof(IssueModel))]
        [HttpPost]
        public ActionResult AddIssue(IssueModel model)
        {
            int postID = model.PostID;
            string topicName = model.TopicName;
            Issue issue = PostManager.AddIssue(postID, topicName);
            HtmlModel result = new HtmlModel();
            if (issue == null)
            {
                result.Message = "Invalid";
            }
            else
            {
                result.Message = "Added Issue!";
                result.Html = BlogStudyHelper.CreateIssueOption(issue);
            }
            return Json(result);
        }

        public ActionResult GetBlogAliases(string blogName)
        {
            return Json(BlogManager.GetAliases(blogName));
        }

        public ActionResult GetProximateTopics(int postID)
        {
            //TODO: Write query
            return Json(null);
        }


        [HttpPost]
        public ActionResult SavePerson(PersonModel model)
        {
            //verify it retrieved/saved correctly
            //set ids
            //set message
            //return Json
            return View();
        }


        [ObjectFilter(Param = "savePostModel", RootType = typeof(SavePostModel))]
        [HttpPost]
        public ActionResult SavePost(SavePostModel savePostModel)
        {
            bool result = Save(savePostModel);
            HtmlModel model = new HtmlModel();
            if (result)
            {
                model.Message = "Saved!";
            }
            else
            {
                model.Message = "Save failed!";
            }
            return Json(model);
        }

        public bool Save(SavePostModel savePostModel ){
            Post post = new Post();
            post.Posters = new List<Poster>();
            foreach (int posterID in savePostModel.Posters)
            {
                Poster poster = new Poster();
                poster.ID = posterID;
                post.Posters.Add(poster);
            }
            post.Permalink = savePostModel.Permalink;
            post.BlogName = savePostModel.BlogName;
            post.Issues = new List<Issue>();
            foreach (string[] issueTokens in savePostModel.Issues)
            {
                Issue issue = new Issue();
                issue.ID = int.Parse(issueTokens[0]);
                issue.AffectiveFrame = issueTokens[1];
                post.Issues.Add(issue);
            }
            post.Links = new List<Link>();
            foreach (string[] linkTokens in savePostModel.Links)
            {
                Link link = new Link();
                link.ID = int.Parse(linkTokens[0]);
                link.Tone = linkTokens[1];
                post.Links.Add(link);
            }
            post.Published = savePostModel.Published;
            post.Title = savePostModel.Title;
            return PostManager.Save(post);
        }

        [HttpPost]
        public ActionResult MergeTopics(Topic discarded, Topic remaining)
        {
            //verify it retrieved/saved correctly
            //set ids
            //set message
            //return Json
            return View();
        }

        /// <summary>
        /// borrowed from http://blog.edwardsdigital.com/post/Rendering-a-Spark-partial-view-to-a-string-or-JSONP-with-ASPNET-MVC.aspx
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        SparkView CreateSparkView(string template)
        {
            // Set up your spark engine goodness.
            var settings = new SparkSettings().SetPageBaseType(typeof(SparkView));
            var templates = new FileSystemViewFolder(Server.MapPath("~/Views"));
            var engine = new SparkViewEngine(settings) { ViewFolder = templates };
            // "Describe" the view (the template, it is a template after all), and its details.  
            var descriptor = new SparkViewDescriptor().AddTemplate(template);
            // Create a spark view engine instance  
            return (SparkView)engine.CreateInstance(descriptor);
        }
    }
}
